所有 ASP.NET Core 範本都包含產生的程式碼中的路由。
基本路由是在Startup.Configure
中的Middleware管線中註冊。(可參考[Day03] Middleware- 我與 ASP.NET Core 3 的 30天)
下列程式碼顯示路由的基本範例:
public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
{
if (env.IsDevelopment()) { app.UseDeveloperExceptionPage(); }
app.UseRouting();
app.UseEndpoints(endpoints =>{
endpoints.MapGet("/", async context => { await context.Response.WriteAsync("Hello World!"); });
});
}
路由會使用由UseRouting與UseEndpoints註冊的Middleware:
上述範例包含使用MapGet方法 ,將單一路由傳送至程式碼端點:
上方的範例中,MapGet方法就是用來定義端點。(Map的使用方法可參照[Day03] Middleware- 我與 ASP.NET Core 3 的 30天
端點可以是:
應用程式中可以比對和執行的端點會在UseEndpoints中設定。例如MapGet、MapPost、MapPut...等等方法會將要求委派連接至路由系統。
除了基本的路由設定之外,我們還可以在Controller及Action中設** 屬性路由 **
屬性路由可以針對每個Controller及Action做自定義的路由,能夠讓作為端點的Action可以更彈性的做路由設計。
套用 Attribute在 Controller 類別
套用 Attribute 在 Action 方法
適合用屬性路由的網址結構
下面就來示範如何設定屬性路由實現此路由
/customers/1/orders
public class OrdersController : ControllerBase
{
[HttpGet("customers/{customerId}/orders")]
public IEnumerable<Order> FindOrdersByCustomer(int customerId) { ... }
}
因為customerId必須為int,所以我們必須加上型別的限制
public class OrdersController : ControllerBase
{
[HttpGet("customers/{customerId:int}/orders")]
public IEnumerable<Order> FindOrdersByCustomer(int customerId) { ... }
}
屬性路由的參數還可以設定預設值或可選參數
public class OrdersController : ControllerBase
{
[HttpGet("{id:int=1}")]
public IEnumerable<Order> Get(int id) { ... }
}
或者設置為可選參數,並讓預設值加在傳入的參數中
public class OrdersController : ControllerBase
{
[HttpGet("{id:int?}")]
public IEnumerable<Order> Get(int id = 1) { ... }
}
在API的Controller中,慣例都會加上 api/ 作為路由前置詞(Route Prefixes)後面再帶上Controller名稱
[Route("api/[controller]")],不過如果今天有某個Action不想要沿用這樣子的前置詞,也可以為特定的Action做出自訂的路由,例如:
[Route("api/[controller]")]
public class OrderController : ControllerBase
{
[HttpGet("~/orders/")]
public IEnumerable<Order> Get()
{
...
}
}
如此就可以直接透過/orders 呼叫到這個Action